/************************************多功能台灯********************************

一、相关功能

1.光敏传感器检测光照强度从而来自动调解灯光的暗亮程度
2.通过按键来控制 改变高低电平的占空比调节灯光的暗亮程度
3.通过语音识别来改变灯光的暗亮程度
4.通过超声波来检测 当检测距离大于特定值的关闭灯光，否则在该模式下默认占空比50%
5.通过红外遥控来控制灯光的暗亮程度
6.定时功能 用户给个值 当达到此值时蜂鸣器发出相应的报警提示

二、菜单界面显示

1.光敏界面
2.时钟界面
3.按键界面
4.语音界面
5.超声波界面
*******************************************************************************
Author:xiao yin
Date:2022-9-15
*******************************************************************************/
#include "stm32f10x.h"
#include "usart.h"
#include "oled.h"
#include "infrared.h"
#include "delay.h"
#include "led.h"
#include "adc.h"
#include "ldr.h"
#include "timer.h"
#include "key.h"
#include "timer2.h"
#include "syn6288.h"
#include "buzzer.h"
#include "ultrasonic.h"
#include "irda.h"


#define Min_duty 0 //最小占空比
#define max_duty  100//最大占空比
extern unsigned char sec;//秒
extern unsigned char min; //分
extern unsigned char hour;//时
extern unsigned int count; //计数变量
extern unsigned char time[6]; //存储时间转换后的值
/******************红外定义******************/
extern uint8_t  frame_flag;
extern uint8_t  isr_cnt;
extern uint8_t  frame_cnt;
uint8_t isr_cnt;  /* 用于计算进了多少次中断 */  
/********************************************/

unsigned int adcx; //光敏值 0-100
unsigned char keyvalue;//按键返回值
unsigned char flag;//界面切换标志
unsigned int current_duty = 100;  //当前占空比 此时灯光最暗
unsigned int value_duty; //设置占空比的值
unsigned char flag_function = 0;//函数功能标志位
unsigned char RxData; //语音接收
unsigned int Time = 120;//定时时间变量
float dis; //接收超声波返回的数据

void main_interface(void);
void menu_interface(void);
void Interface1(void);
void Interface2(void);
void Interface3(void);
void  Interface4(void);
void Interface5(void);
void Ldr_Tackle(void);
void Time_Display(void);
void KEY_Tackle_Puty(void);
void Voice_Tackle(void);


/*********************************************三个界面显示函数*****************************/
//主页面
void main_interface(void)
{
//		OLED_Clear(0);
//		delay_ms(10);
	
		OLED_ShowCHinese(6,0,0);//智
		OLED_ShowCHinese(26,0,1);//能
		OLED_ShowCHinese(46,0,2);//台
		OLED_ShowCHinese(66,0,3);//灯
		OLED_ShowCHinese(86,0,4);//系
		OLED_ShowCHinese(106,0,5);//统	 
		OLED_ShowNum(6,4,2021,4,16);
		OLED_ShowCHinese_TWO(40,4,0);//年 
		OLED_ShowNum(60,4,11,2,16);
		OLED_ShowCHinese_TWO(74,4,1);//月 
		OLED_ShowNum(92,4,17,2,16);
		OLED_ShowCHinese_TWO(108,4,2);//日 

		
	
}

//菜单页面
void menu_interface(void)
{
//	OLED_Clear(0);
//		delay_ms(10);
//	
	 OLED_ShowString(20,0,(unsigned char *)"Function",8);
	 OLED_ShowString(20,2,(unsigned char *)"1.Light Test",8);
	 OLED_ShowString(20,4,(unsigned char *)"2.Time Clock",8); 
	 OLED_ShowString(20,6,(unsigned char *)"3.KEY Test",8); 
	
}
//光敏功能界面1
void Interface1(void)
{
	
//	 OLED_Clear(0);
//		delay_ms(10);
//	
    OLED_ShowString(20,0,(unsigned char *)"Light Test",8);
	  OLED_ShowString(10,3,(unsigned char *)"VALUE:",8);
	  OLED_ShowString(10,5,(unsigned char *)"DUTY :",8);
	  OLED_ShowString(10,7,(unsigned char *)"MODE :",8);
		OLED_ShowNum(60,3,adcx/100,2,4);
		OLED_ShowNum(68,3,adcx/10%10,2,4);
		OLED_ShowNum(76,3,adcx%10,2,4);
		OLED_ShowNum(60,5,(100-current_duty)/100,2,4); //百位
		OLED_ShowNum(68,5,(100-current_duty)/10%10,2,4);//十位
		OLED_ShowNum(76,5,(100-current_duty)%10,2,4);//个位
		OLED_ShowNum(60,7,1,2,4);//mode	 
		
}


//时钟功能界面2
void Interface2(void)
{
	 //界面清屏
//	 OLED_Clear(0);
//	delay_ms(10);
	//刷新重新要显示的数据
	 OLED_ShowString(26,1,(unsigned char *)"Time Clock",8); 
	 
	 OLED_ShowString(30,5,(unsigned char *)"MODE :",8); 
	
}


//按键功能界面3
void Interface3(void)
{
	 //界面清屏
//	 OLED_Clear(0);
//	 delay_ms(10);
	//刷新重新要显示的数据
	 OLED_ShowString(40,0,(unsigned char *)"KEY",8); 
	 OLED_ShowString(10,3,(unsigned char *)"DUTY :",8);
	 OLED_ShowString(10,5,(unsigned char *)"MODE :",8);
	 OLED_ShowNum(68,3,(100-current_duty)/100,2,4); //百位
	 OLED_ShowNum(76,3,(100-current_duty)/10%10,2,4);//十位
	 OLED_ShowNum(84,3,(100-current_duty)%10,2,4);//个位
	 OLED_ShowNum(68,5,3,2,4);//mode	 
	 
}

/*****************************************************************************************/

//功能界面四 语音模式
void  Interface4(void)
{
	
	
	
		OLED_ShowString(20,0,(unsigned char *)"Voice Test",8);
	  OLED_ShowString(10,3,(unsigned char *)"DUTY :",8);
	  OLED_ShowString(10,5,(unsigned char *)"MODE :",8);
		OLED_ShowNum(60,3,(100-current_duty)/100,2,4); //百位
		OLED_ShowNum(68,3,(100-current_duty)/10%10,2,4);//十位
		OLED_ShowNum(76,3,(100-current_duty)%10,2,4);//个位
		OLED_ShowNum(60,5,4,2,4);//mode	 
}


//超声波测距界面
void Interface5(void)
{
		OLED_ShowString(20,0,(unsigned char *)"CSB Test",8);
	  OLED_ShowString(10,4,(unsigned char *)"DIS:",8);	 
	  OLED_ShowString(10,6,(unsigned char *)"DUTY :",8);
		OLED_ShowNum(60,4,(int)dis/100,2,4); //百位
		OLED_ShowNum(68,4,(int)dis/10%10,2,4);//十位
		OLED_ShowNum(76,4,(int)dis%10,2,4);//个位	
		OLED_ShowNum(60,6,(100-current_duty)/100,2,4); //百位
		OLED_ShowNum(68,6,(100-current_duty)/10%10,2,4);//十位
		OLED_ShowNum(76,6,(100-current_duty)%10,2,4);//个位
}


/*********************************************功能函数*********************************/
//光敏电阻改变led灯的亮度
void Ldr_Tackle(void)
{
		adcx = Lsens_Get_Val();
		if(adcx <=30 )
		{
			current_duty = 10;
		}
		else if(adcx  > 30 && adcx <= 50)
		{
			 current_duty = 40;
			
		}
		else if(adcx >50 && adcx <=70)
		{
			 current_duty = 60;
		}
    else if(adcx>70 && adcx <= 90)		
		{
				current_duty = 80;
		}
		else{
				current_duty = 0;
		}	
//		TIM_SetCompare2(TIM3,current_duty);
		//printf("光线强度为:%d\n",adcx);
		//printf("占空比为：%d\n",100-current_duty);
}



//对时间进行显示
void Time_Display(void)
{
	 unsigned char i;
	 OLED_ShowNum(30,3,time[0],2,4);
	 OLED_ShowNum(38,3,time[1],2,4);
	 OLED_ShowChar(46,3,':',4);
	 OLED_ShowNum(52,3,time[2],2,4);
	 OLED_ShowNum(60,3,time[3],2,4);
	 OLED_ShowChar(68,3,':',4);
	 OLED_ShowNum(74,3,time[4],2,4);
	 OLED_ShowNum(82,3,time[5],2,4);	
	 OLED_ShowNum(74,5,2,2,4);//mode	
	//如果超过
	if(sec >= Time)  
	{
		for(i =0; i< 4;i++)
		{
			
			Buzzer_On();
			delay_ms(500);
			Buzzer_Off();			
		}
		 sec = 0;
	}
}



//按键处理函数通过key2 key3两个按键来控制灯光的占空比
//key 2进行占空比的累加 key3 进行占空比的减
void KEY_Tackle_Puty(void)
{
	keyvalue = 0;
	keyvalue = KEY_Scan();
		//当占空比加到最大值的时候重新从最小的占空比开始 当占空比减到最小值的时候重新从最大值开始
	if(keyvalue == 3 )//为1的时候进行占空比加
	{
		current_duty+=20;
		if(current_duty >=max_duty )
			{
				current_duty = 0;
			}
		}
		if(keyvalue == 4)
		{
			current_duty-=20;
			if(current_duty <= Min_duty)
				{
					current_duty = 100;
				}
		}	
	

		//printf("keyvalue = %d\n",keyvalue);	
}




 //超声波处理函数
void Csb_Tackle(void)
{
	dis = Senor_Using();
	printf("current dis = %.2f\n",dis);
	if(dis >= 500)
	{	
			Buzzer_On();
			delay_ms(500);
			Buzzer_Off();
			current_duty = 100; //检测不到物体关闭灯光	
	}
	else
	{
		current_duty = 50; //检测到时候 默认 一半
	}
	
}


//语音功能处理
void Voice_Tackle(void)
{
	if(RxData == '0')
	{
		Buzzer_On();
		delay_ms(500);
		Buzzer_Off();
		 current_duty = 100; //关闭
	}
	else if(RxData == '1')
	{
		current_duty = 20;	
		//printf("rec 1 success\n");
	}
	else if(RxData == '2')
	{
		current_duty = 50;
	//	printf("res 2 success\n");
	}
	else if(RxData == '3')
	{
		current_duty = 90;
		//printf("re3 success\n");
	}
	else if(RxData == '4')
	{
			Time = 10;	
			//printf("re 4 success\n");
	}
	else if(RxData == '5')
	{
		Time = 20;
		//printf("re 5 success\n");
		
	}
	else if(RxData == '6')
	{
		Time = 30;
		//printf("re 6 success\n");
	}	
	else {	
		//printf("cmd is error\n");
	}	
}





//红外功能处理
//通过红外遥控进行对占空比的调节和对定时的时间进行加减
void Irda_Tackle(void)
{
	unsigned  char key_val;
	if( frame_flag == 1 ) /* 一帧红外数据接收完成 */
    {
      key_val = IrDa_Process();
      printf("\r\n key_val=%d \r\n",key_val);
      printf("\r\n 按键次数frame_cnt=%d \r\n",frame_cnt);
      printf("\r\n 中断次数isr_cnt=%d \r\n",isr_cnt);    
      /* 不同的遥控器面板对应不同的键值，需要实际测量 */
      switch( key_val )
      {
        case 0:
          printf("\r\n key_val=%d \r\n",key_val);
          printf("\r\n Error \r\n");
        break;
        
        case 162:
          printf("\r\n key_val=%d \r\n",key_val);
          printf("\r\n POWER \r\n");
        break;
        
        case 226:
          printf("\r\n key_val=%d \r\n",key_val);
          printf("\r\n MENU \r\n");
        break;
        
        case 34:
          printf("\r\n key_val=%d \r\n",key_val);
          printf("\r\n TEST \r\n");
        break;
        
        case 2:
          printf("\r\n key_val=%d \r\n",key_val);
          printf("\r\n + \r\n");
					current_duty += 10;
        break;
        
        case 194:
          printf("\r\n key_val=%d \r\n",key_val);
          printf("\r\n RETURN \r\n");
        break;
        
        case 224:
          printf("\r\n key_val=%d \r\n",key_val);
          printf("\r\n |<< \r\n");
        break;
        
        case 168:
          printf("\r\n key_val=%d \r\n",key_val);
          printf("\r\n > \r\n");
        break;
        
        case 144:
          printf("\r\n key_val=%d \r\n",key_val);
          printf("\r\n >>| \r\n");
        break;
        
        case 104:
          printf("\r\n key_val=%d \r\n",key_val);
          printf("\r\n 0 \r\n");
				current_duty = 100;
        break;
        
        case 152:
          printf("\r\n key_val=%d \r\n",key_val);
          printf("\r\n - \r\n");
				  current_duty -= 10;
        break;
        
        case 176:
          printf("\r\n key_val=%d \r\n",key_val);
          printf("\r\n C \r\n");
        break;
        
        case 48:
          printf("\r\n key_val=%d \r\n",key_val);
          printf("\r\n 1 \r\n");
				current_duty = 5;
        break;
        
        case 24:
          printf("\r\n key_val=%d \r\n",key_val);
          printf("\r\n 2 \r\n");
				current_duty = 15;
        break;
        
        case 122:
          printf("\r\n key_val=%d \r\n",key_val);
          printf("\r\n 3 \r\n");
				current_duty = 25;
        break;
        
        case 16:
          printf("\r\n key_val=%d \r\n",key_val);
          printf("\r\n 4 \r\n");
				current_duty = 40;
        break;
        
        case 56:
          printf("\r\n key_val=%d \r\n",key_val);
          printf("\r\n 5 \r\n");
				current_duty = 60;
        break;  
        case 90:
          printf("\r\n key_val=%d \r\n",key_val);
          printf("\r\n 6 \r\n");
				current_duty = 80;
        break;
          case 66:
          printf("\r\n key_val=%d \r\n",key_val);
          printf("\r\n 7 \r\n");
					current_duty = 90;
        break;
        
        case 74:
          printf("\r\n key_val=%d \r\n",key_val);
          printf("\r\n 8 \r\n");
					Time += 10;
        break;   
        case 82:
          printf("\r\n key_val=%d \r\n",key_val);
          printf("\r\n 9 \r\n");
					Time -= 10;
        break;
        
        default:       
        break;
      }      
    }
}

/**********************************************************************************************/

//通过按键来进行界面的切换
unsigned char Key_Mode(void)
{
//	delay_ms(500);
	keyvalue = KEY_Scan(); //按键1来进行模式的切换
	if(keyvalue == 1) //判断按键1是否被按下
	{
		flag++;	
	}	
	if(keyvalue == 2)
	{
			flag--;
	}
		switch(flag)
		{	
			case 1:OLED_Clear(0);main_interface();break;
			case 2:OLED_Clear(0);menu_interface();break;
			case 3:OLED_Clear(0);Interface1();flag_function=1;break;
			case 4:OLED_Clear(0);Interface4();flag_function=2;break;
			case 5:OLED_Clear(0);Interface2();flag_function=3;break;
			case 6:OLED_Clear(0);Interface5();flag_function=4;break;
			case 7:OLED_Clear(0);Interface3();flag_function=5;break;
			default:break;
		}
	return flag_function; //返回功能函数的标志位
}




/*****************************************主函数*********************************/
int main(void)
{		
	 unsigned char value =0;
   Infrared_GPIO_INIT();
	 KEY_GPIO_INIT();//按键初始化
	 USART_INIT(9600); //串口初始化
	 LED_GPIO_INIT();// led初始化
	 IrDa_Init();    //红外初始化
	 CH_SR04_Init(); //超声波初始化
	 Buzzer_GPIO_Init();//蜂鸣器初始化
	 Lsens_Init(); //光敏传感器初始化
	 TIM3_PWM_Init(100-1,7200-1);//pwm控制初始化 1hkz  计数到100为10ms
	 OLED_Init();			//初始化OLED  
	 OLED_Clear(0);	
	 while(1)
	 {
		 Irda_Tackle();
		 /*
			value = Key_Mode();	 
		  if(value == 1)
			{
				Ldr_Tackle(); //光敏模式处理			
			}
			else if(value == 2)
			{
				Voice_Tackle(); //语音模式功能处理			
			}		
			else if(value == 3)
			{
				Time_Display(); //定时模式处理			
			}
			else if(value == 4)
			{
				Csb_Tackle();
				
			}	
		 else if(value == 5)
		 {
			KEY_Tackle_Puty(); //按键模式功能处理
		}
	 	TIM_SetCompare2(TIM3,current_duty);
		 */
 }
}

 
 
/***********************************串口中断****************************/
 void USART1_IRQHandler(void){
      if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
            USART_ClearITPendingBit(USART1, USART_IT_RXNE);
            RxData=USART_ReceiveData(USART1); 
						if(RxData == '0')
						{
							Time = 20;
							Buzzer_On();
							delay_ms(50);
							Buzzer_Off();
							
						}
						else if( RxData == '1')
						{
							current_duty = 10;
							Buzzer_On();
							delay_ms(50);
							Buzzer_Off();
						}
						else if(RxData == '2')
						{
							current_duty = 50;
							Buzzer_On();
							delay_ms(50);
							Buzzer_Off();
						//	printf("res 2 success\n");
						}
						else if(RxData == '3')
						{
							current_duty = 90;
							Buzzer_On();
							delay_ms(50);
							Buzzer_Off();
							//printf("re3 success\n");
						}
						else if(RxData == '4')
						{
								Time = 10;
								Buzzer_On();
							delay_ms(50);
							Buzzer_Off();							
								//printf("re 4 success\n");
						}
						else if(RxData == '5') //关闭灯光
						{
							current_duty =100; 
							Buzzer_On();
							delay_ms(50);
							Buzzer_Off();
							//printf("re 5 success\n");
							
						}
						else if(RxData == '6')
						{
							Time = 30;
							Buzzer_On();
							delay_ms(50);
							Buzzer_Off();
							//printf("re 6 success\n");
						}	
						else {	
							//printf("cmd is error\n");
						}	
						
						 USART_SendData(USART1,RxData);
						}
}




